package com.zenithmind.gateway.context;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 默认请求上下文管理器实现
 * 专门负责管理请求的上下文信息
 * 遵循单一职责原则：只负责请求上下文的管理逻辑
 */
@Slf4j
@Component
public class DefaultRequestContextManager implements RequestContextManager {
    
    private static final ThreadLocal<RequestContext> CONTEXT_HOLDER = new ThreadLocal<>();

    @Override
    public RequestContext createContext(ServerHttpRequest request) {
        String requestId = UUID.randomUUID().toString();
        String path = request.getURI().getPath();
        String method = request.getMethod().name();
        String remoteAddress = request.getRemoteAddress() != null ? 
            request.getRemoteAddress().getHostString() : "unknown";
        
        return new DefaultRequestContext(requestId, path, method, remoteAddress);
    }

    @Override
    public RequestContext getCurrentContext() {
        return CONTEXT_HOLDER.get();
    }

    @Override
    public void setCurrentContext(RequestContext context) {
        CONTEXT_HOLDER.set(context);
        log.trace("设置请求上下文: {}", context.getRequestId());
    }

    @Override
    public void clearCurrentContext() {
        RequestContext context = CONTEXT_HOLDER.get();
        if (context != null) {
            log.trace("清除请求上下文: {}", context.getRequestId());
            CONTEXT_HOLDER.remove();
        }
    }
    
    /**
     * 默认请求上下文实现
     */
    private static class DefaultRequestContext implements RequestContext {
        private final String requestId;
        private final String path;
        private final String method;
        private final String remoteAddress;
        private final long startTime;
        
        private String userId;
        private String targetService;
        
        public DefaultRequestContext(String requestId, String path, String method, String remoteAddress) {
            this.requestId = requestId;
            this.path = path;
            this.method = method;
            this.remoteAddress = remoteAddress;
            this.startTime = System.currentTimeMillis();
        }
        
        @Override
        public String getRequestId() { return requestId; }
        
        @Override
        public String getPath() { return path; }
        
        @Override
        public String getMethod() { return method; }
        
        @Override
        public String getUserId() { return userId; }
        
        @Override
        public String getRemoteAddress() { return remoteAddress; }
        
        @Override
        public String getTargetService() { return targetService; }
        
        @Override
        public long getStartTime() { return startTime; }
        
        @Override
        public void setUserId(String userId) { this.userId = userId; }
        
        @Override
        public void setTargetService(String targetService) { this.targetService = targetService; }
    }
}
